package main;

import main.components.JGlyphButton;
import main.components.TreeSmet;
import main.components.TreeTitul;
import main.objects.SmetNode;
import main.objects.SmetResource;
import main.objects.TreeTitulNode;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.BorderUIResource;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

public class MainFrame extends JFrame{

    public TreeTitulNode ROOT_NODE;
    public static TreeTitulNode SELECTED_EPS, CURRENT_TITUL;
    public static ArrayList<SmetNode> BUFFER_COPY, BUFFER_CUT;

    public static HashMap<String, TreeTitulNode> ALL_EPS;
    public static HashMap<String, SmetNode> ALL_SMET;

    public static TreeTitul treeTitul;
    public static TreeSmet treeSmet;

    public static JGlyphButton tbBtnAdd, tbBtnDelete, tbBtnRename, tbBtnImport;

    public static JMenu jMenu2;

    public MainFrame() {

        try {

            loadData();
            BUFFER_COPY = new ArrayList<>();
            BUFFER_CUT = new ArrayList<>();

        } catch (SQLException e) {
            e.printStackTrace();
        }
        init();
        setVisible(true);

    }

    //region Инициализация компонентов
    public void init() {

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //region Параметры окна
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setTitle("importFactage");
        setLayout(new GridBagLayout());
        //endregion

        //region Компоненты

        //region Панель меню
        JMenuBar mainMenuBar = new JMenuBar();
        add(mainMenuBar, new GridBagConstraints(0, 0, 1, 1, 0.1, 0.1, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

        JMenu jMenu1 = new JMenu("Файл");
        jMenu1.setMargin(new java.awt.Insets(0, 10, 0, 10));
        mainMenuBar.add(jMenu1);

        JMenuItem jMenuItem1_1 = new JMenuItem("Выход");
        jMenuItem1_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                dispose();
            }
        });
        jMenu1.add(jMenuItem1_1);

        jMenu2 = new JMenu("Правка");
        jMenu2.setMargin(new java.awt.Insets(0, 10, 0, 10));
        mainMenuBar.add(jMenu2);

        JMenuItem jMenuItem2_0 = new JMenuItem("Вырезать Смету");
        jMenuItem2_0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                treeSmet.cutSmetToBuffer();
            }
        });
        jMenu2.add(jMenuItem2_0);

        JMenuItem jMenuItem2_1 = new JMenuItem("Копировать Смету");
        jMenuItem2_1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                treeSmet.copySmetToBuffer();
            }
        });
        jMenu2.add(jMenuItem2_1);

        JMenuItem jMenuItem2_2 = new JMenuItem("Вставить Смету");
        jMenuItem2_2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                treeSmet.pasteSmet();
            }
        });
        jMenu2.add(jMenuItem2_2);

        jMenu2.add(new JPopupMenu.Separator());

        JMenuItem jMenuItem2_4 = new JMenuItem("Переименовать смету");
        jMenuItem2_4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                treeSmet.renameSmet();
            }
        });
        jMenuItem2_4.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
        jMenuItem2_4.setIcon(new ImageIcon(getClass().getResource("components/icons/rename12x12.png")));
        jMenu2.add(jMenuItem2_4);

        jMenu2.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent changeEvent) {

                System.out.println("Action!");
                jMenu2.getItem(0).setEnabled(treeSmet.SELECTED_SMET != null && treeSmet.SELECTED_SMET.isSmet());
                jMenu2.getItem(1).setEnabled(treeSmet.SELECTED_SMET != null && treeSmet.SELECTED_SMET.isSmet());
                jMenu2.getItem(2).setEnabled(!BUFFER_COPY.isEmpty() || !BUFFER_CUT.isEmpty());
                jMenu2.getItem(4).setEnabled(treeSmet.SELECTED_SMET != null && treeSmet.SELECTED_SMET.isSmet());

            }
        });

        //endregion



        treeSmet = new TreeSmet();
        treeSmet.setRootVisible(true);
        treeSmet.setBorder(new BorderUIResource.CompoundBorderUIResource(BorderFactory.createLineBorder(Color.LIGHT_GRAY), BorderFactory.createEmptyBorder(10,10,10,10)));

        treeTitul = new TreeTitul(ROOT_NODE, treeSmet);
        treeTitul.setRootVisible(true);
        treeTitul.setBorder(new BorderUIResource.CompoundBorderUIResource(BorderFactory.createLineBorder(Color.LIGHT_GRAY), BorderFactory.createEmptyBorder(10,10,10,10)));
        treeTitul.setRowHeight(25);

        //region toolBar
        JToolBar toolBarTitul = new JToolBar();
        toolBarTitul.setFloatable(false);
        toolBarTitul.setOrientation(javax.swing.SwingConstants.VERTICAL);
        toolBarTitul.setPreferredSize(new Dimension(50, 500));

        //region Кнопка добавления элементов
        tbBtnAdd = new JGlyphButton("icons/add.png");
        tbBtnAdd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                treeTitul.addTitulNode();
            }
        });
        tbBtnAdd.setEnabled(false);
        tbBtnAdd.setToolTipText("Добавить элемент (Insert)");
        toolBarTitul.add(tbBtnAdd);
        //endregion

        //region Кнопка импорта элементов
        tbBtnImport = new JGlyphButton("icons/importFromPrima.png");
        tbBtnImport.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                //treeTitul.removeNodeDialogShow();
            }
        });
        tbBtnImport.setEnabled(false);
        tbBtnImport.setToolTipText("Импорт структуры из WBS");
        toolBarTitul.add(tbBtnImport);
        //endregion

        //region Кнопка переименования элементов
        tbBtnRename = new JGlyphButton("icons/rename.png");
        tbBtnRename.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                treeTitul.renameTitulNode();
            }
        });
        tbBtnRename.setEnabled(false);
        tbBtnRename.setToolTipText("Переименовать (F2)");
        toolBarTitul.add(tbBtnRename);
        //endregion

        //region Кнопка удаления элементов
        tbBtnDelete = new JGlyphButton("icons/delete.png");
        tbBtnDelete.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                treeTitul.removeNodeDialogShow();
            }
        });
        tbBtnDelete.setEnabled(false);
        tbBtnDelete.setToolTipText("Удалить (Delete)");
        toolBarTitul.add(tbBtnDelete);
        //endregion

        toolBarTitul.add(new JSeparator());
        //endregion

        JPanel panelTitul = new JPanel();
        panelTitul.setLayout(new GridBagLayout()); 

        JLabel titulLabel = new JLabel("Структура разделов");
        titulLabel.setFont(new Font("Segoe UI", Font.PLAIN, 15));

        panelTitul.add(toolBarTitul, new GridBagConstraints(0, 0, 1, 2, 0, 1, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(43, 0, 0, 0), 0, 0));
        panelTitul.add(titulLabel, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(20, 0, 4, 0), 0, 0));
        panelTitul.add(new JScrollPane(treeTitul.getTree()), new GridBagConstraints(1, 1, 1, 1, 10.0, 0.1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));

        JSplitPane jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, panelTitul, new JScrollPane(treeSmet.getTree()));
        jSplitPane.setDividerLocation(250);
        //endregion

        add(jSplitPane, new GridBagConstraints(0, 1, 1, 1, 100, 100, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));

    }
    //endregion

    private void loadData() throws SQLException {

        ALL_EPS = new HashMap<>();
        ALL_SMET = new HashMap<>();
        ROOT_NODE = new TreeTitulNode("Проекты", 0);
        ALL_EPS.put("0-root", ROOT_NODE);

        FactageSmet.IMPORT_FACTAGE_CONNECTION = MsSQLConnect.ConnectDB("ImportFactage");
        ResultSet rs;

        //region Загрузка Титулов
        Statement stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM Titul");

        while (rs.next()) {

            TreeTitulNode titulNode = new TreeTitulNode(
                    rs.getString("name"),
                    rs.getInt("id"),
                    rs.getString("code"));

            ALL_EPS.put(rs.getInt("id") + "-titul", titulNode);

        }

        rs.close();
        stat.close();
        //endregion

        //region Загрузка ресурсов
        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM SmetResources");

        while (rs.next()) {

            SmetResource rsrc = new SmetResource(rs);
            ALL_EPS.get(rsrc.getTitulId() + "-titul").getTitulResources().put(rsrc.getCode(), rsrc);

        }

        rs.close();
        stat.close();
        //endregion

        //region Загрузка EPS
        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM EPS");

        while (rs.next()) {

            TreeTitulNode epsNode = new TreeTitulNode(rs, "EPS");
            ALL_EPS.put(rs.getInt("id") + "-eps", epsNode);

        }

        rs.close();
        stat.close();
        //endregion

        //region Загрузка Смет
        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM Smet ORDER BY change");

        ALL_SMET.put("smethead", new SmetNode("smethead"));

        while (rs.next()) {

            SmetNode newSmet = new SmetNode(rs, "smet");

            ALL_SMET.put(rs.getInt("id") + "-smet", newSmet);

            if (ALL_EPS.containsKey(rs.getInt("eps_id") + "-eps")) {
                if (ALL_EPS.get(rs.getInt("eps_id") + "-eps").getSmets().isEmpty()) ALL_EPS.get(rs.getInt("eps_id") + "-eps").getSmets().add(ALL_SMET.get("smethead"));

                ALL_EPS.get(rs.getInt("eps_id") + "-eps").getSmets().add(newSmet);
            }

        }

        rs.close();
        stat.close();
        //endregion

        //region Загрузка Разделов new
        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM Chapter ORDER BY smet_id, num");

        while (rs.next()) {

            SmetNode newChapter = new SmetNode (rs, "chapter");
            ALL_SMET.put(newChapter.getId() + "-chapter", newChapter);
            ALL_SMET.get(newChapter.getSmetId() + "-smet").add(newChapter);

        }

        rs.close();
        stat.close();
        //endregion

        //region Загрузка заголовков
        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM Header ORDER BY smet_id, chapter_id, id");

        while (rs.next()) {

            SmetNode newHeader = new SmetNode (rs, "header");
            ALL_SMET.put(newHeader.getId() + "-header", newHeader);

        }

        rs.close();
        stat.close();
        //endregion

        //region Загрузка Сметных строк
        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();

        ArrayList<Integer> lastLines = new ArrayList<>();

        rs = stat.executeQuery("select ss.id\n" +
                "\tfrom [importFactage].[dbo].[Smr] as ss\n" +
                "\tinner join (select smet_id, max(num) as maxnum from [importFactage].[dbo].[Smr] group by smet_id) as groupedsmr\n" +
                "\ton ss.smet_id = groupedsmr.smet_id\n" +
                "\tand ss.num = groupedsmr.maxnum");

        while (rs.next()) {
            lastLines.add(rs.getInt("id"));
        }

        rs.close();
        stat.close();

        stat = FactageSmet.IMPORT_FACTAGE_CONNECTION.createStatement();
        rs = stat.executeQuery("SELECT * FROM Smr ORDER BY smet_id, chapter_id, header_id, num");

        while (rs.next()) {

            SmetNode newSmr = new SmetNode(rs, "smr");

            ALL_SMET.put(rs.getInt("id") + "-smr", newSmr);

            if (lastLines.contains(newSmr.getId())) {
                newSmr.setLast(true);
            }

            SmetNode parent = ALL_SMET.get(newSmr.getHeaderId() != 0 ? newSmr.getHeaderId() + "-header" : newSmr.getChapterId() != 0 ? newSmr.getChapterId() + "-chapter" : newSmr.getSmetId() + "-smet");

            if (parent.isHeader() && parent.getChapterId() != null) {
                if (ALL_SMET.get(parent.getChapterId() + "-chapter").getChildren() == null || !ALL_SMET.get(parent.getChapterId() + "-chapter").getChildren().contains(parent))
                ALL_SMET.get(parent.getChapterId() + "-chapter").add(parent);
            }

            if (parent.getChildCount() == 0) {
                ALL_SMET.put("smrhead", new SmetNode("smrhead"));
                parent.add(ALL_SMET.get("smrhead"));
            }
            parent.add(newSmr);

        }

        rs.close();
        stat.close();
        //endregion

        FactageSmet.IMPORT_FACTAGE_CONNECTION.close();
        hierarchyData();

    }

    private void hierarchyData() {

        ArrayList<TreeTitulNode> nodeList = new ArrayList<>(ALL_EPS.values());

        Collections.sort(nodeList, new Comparator<TreeTitulNode>() {
            @Override
            public int compare(TreeTitulNode treeTitulNode, TreeTitulNode treeTitulNode2) {
                if (treeTitulNode.getId() < treeTitulNode2.getId()) {
                    return -1;
                } else if (treeTitulNode.getId() > treeTitulNode2.getId()) {
                    return 1;
                }
                return 0;
            }
        });

        for (TreeTitulNode node : nodeList) {
            if (node.getId() > 0) {
                if (node.isTitul) {
                    ROOT_NODE.add(node);
                } else {
                    if (node.getParentId() == 0) {
                        ALL_EPS.get(node.getTitulId()+"-titul").add(node);
                    } else {
                        ALL_EPS.get(node.getParentId()+"-eps").add(node);
                    }
                }
            }
        }

    }

}
